package wangwenjun.phase1.synchronizeddemo.defect;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.concurrent.TimeUnit;

/**
 * @author ChangLiang
 * @date 2020/6/10
 */
public class SynchronizedDefectTest {

    public synchronized void syncMethod() {
        try {
            TimeUnit.HOURS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    @DisplayName("test synchronized defect")
    public void test() throws InterruptedException {
        SynchronizedDefectTest defectTest = new SynchronizedDefectTest();
        Thread t1 = new Thread(defectTest::syncMethod, "T1");
        t1.start();
        //make sure the t1 started.
        TimeUnit.MILLISECONDS.sleep(2);

        /*T2 线程启动执行syncMethod 方法时会进入阻塞， T2什么时候能够获得syncMethod 的执行完全取决于Tl 何时对其释放，
        如果T2 计划最多l 分钟获得执行权，否则就放弃，很显然这种方式是做不到的，
        这也就是前面所说的阻塞时长无法控制*/
        Thread t2 = new Thread(defectTest::syncMethod, "T2");
        t2.start();
        //make sure the t2 started.
        TimeUnit.MILLISECONDS.sleep(2);

        /**
         * T2 若因争抢某个monitor 的锁而进入阻塞状态，那么它是无法中断的，
         * 虽然可以设置T2 线程的interrupt 标识，但是synchronized 阻塞不像sleep 和wait 方法一样
         * 能够捕获得到中断信号
         */
        t2.interrupt();
        System.out.println(t2.isInterrupted());
        System.out.println(t2.getState());

        Thread.currentThread().join();
    }
}
